package com.yvan.leto.server.controller;

import com.google.common.base.Splitter;
import com.google.common.base.VerifyException;
import com.google.common.collect.Lists;
import com.yvan.YvanUtil;
import com.yvan.leto.server.dao.RepositoryPersistent;
import com.yvan.leto.server.domain.ConfigFileContent;
import com.yvan.leto.server.domain.ConfigFileEnv;
import com.yvan.leto.server.domain.Env;
import com.yvan.leto.server.domain.LsVo;
import com.yvan.leto.server.service.EnvService;
import com.yvan.leto.server.utils.FileUtils;
import com.yvan.leto.server.utils.HttpJsonPayloadParser;
import com.yvan.leto.server.utils.VerifyHelper;
import com.yvan.platform.ResultModel;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;


@Slf4j
@RestController
public class ConfigFileController {

    @Autowired
    private RepositoryPersistent repositoryPersistent;

    @Autowired
    private EnvService envService;

    @DeleteMapping("/raw/**")
    public Object configFileDelete(HttpServletRequest request) {
        Object[] paths = parsePath(request);
        if (repositoryPersistent.delete(envService.envFindAllWithEmpty(), FileUtils.normalizePath(paths))) {
            return ResultModel.newSuccess().putMsg("删除成功!");
        }
        return ResultModel.newFail("删除失败");
    }

    @GetMapping("/config_file_edit/verify_name")
    public Object verifyName(@RequestParam("path") String path) {
        String r;
        try {
            r = VerifyHelper.configFilePath(path);
        } catch (VerifyException e) {
            return ResultModel.newFail(e.getMessage());
        }

        return ResultModel.newSuccess().set("href", r);
    }

    @PutMapping("/raw/**")
    public Object configFilePost(HttpServletRequest request) throws IOException {
        Object[] paths = parsePath(request);
        HttpJsonPayloadParser parser = new HttpJsonPayloadParser(request);
        ConfigFileContent param = parser.getJsonWapper().asObject(ConfigFileContent.class);
        if (!FileUtils.normalizePath(paths).equals(param.getFullProfileName())) {
            return ResultModel.newFail("路径非法!");
        }
        repositoryPersistent.repositorySaveFile(param);
        return ResultModel.newSuccess().putMsg("保存成功!");
    }

    @GetMapping("/edit/**")
    public ModelAndView edit(HttpServletRequest request) {
        ResultModel model = fillModel(parsePath(request));
        return new ModelAndView("/cf_edit.ftl", model);
    }

    @GetMapping("/edit2/**")
    public ModelAndView edit2(HttpServletRequest request) {
        ResultModel model = fillModel(parsePath(request));
        return new ModelAndView("/cf_edit2.ftl", model);
    }

    @GetMapping("/view/**")
    public ModelAndView view(HttpServletRequest request) {
        ResultModel model = fillModel(parsePath(request));
        return new ModelAndView("/cf_view.ftl", model);
    }

    @GetMapping("/tree/**")
    public ModelAndView tree(HttpServletRequest request) {
        Object[] paths = parsePath(request);
        ResultModel model = new ResultModel();
        model.put("path", FileUtils.normalizePath(paths));
        model.put("paths", paths);

        List<LsVo> ls = Lists.newArrayList();
        if (paths.length > 0) {
            ls.add(new LsVo("..", false));
        }
        for (String fn : repositoryPersistent.repositoryDirectoryList(paths)) {
            ls.add(new LsVo(fn, false));
        }
        for (String fn : repositoryPersistent.repositoryFileList(paths)) {
            ls.add(new LsVo(fn, true));
        }

        model.put("ls", YvanUtil.toJsonPretty(ls));
        return new ModelAndView("/cf_tree.ftl", model);
    }

    public ResultModel fillModel(Object... paths) {
        final String envName = FileUtils.getProfileName(paths);

        val path = FileUtils.normalizePath(paths);
        ConfigFileContent param = new ConfigFileContent();
        param.setFullProfileName(FileUtils.normalizePath(paths));
        param.setExists(repositoryPersistent.repositoryFileExists(paths));
        if (param.isExists()) {
            param.setContent(repositoryPersistent.repositoryFileContent(paths));
        } else {
            param.setContent("");
        }
        param.setEnv(envName);
        param.setPath(path);

        ResultModel model = new ResultModel();
        model.put("full_profile_name", param.getFullProfileName());
        model.put("paths", paths);
        model.put("content_json", YvanUtil.toJson(param));
        model.put("exists", param.isExists());
        model.put("ext", FileUtils.getExtName(paths));

        List<ConfigFileEnv> envs = Lists.newArrayList();
        envs.add(new ConfigFileEnv("", "common"));
        for (Env env : envService.selectAll()) {
            envs.add(new ConfigFileEnv(env.getName(), env.getCaption()));
        }
        for (ConfigFileEnv env : envs) {
            if (StringUtils.isEmpty(env.getName()) && StringUtils.isEmpty(envName)) {
                env.setActived(true);
            } else if (env.getName().equals(envName)) {
                env.setActived(true);
            }
            env.setFullProfileName(FileUtils.getFullProfileName(env.getName(), paths));
            env.setHas(repositoryPersistent.repositoryFileExists(env.getFullProfileName()));
        }
        model.put("env_has", envs);
        return model;
    }

    private Object[] parsePath(HttpServletRequest request) {
        String uri = request.getRequestURI();
        List<String> ls = Splitter.on("/").omitEmptyStrings().splitToList(uri);
        String[] r = new String[ls.size() - 1];
        for (int i = 1; i < ls.size(); i++) {
            r[i - 1] = ls.get(i);
        }
        return r;
    }


}
